/* GameArea.java
 * 
 * Alfred Olschnoegger
 * 27.05.2008
 */

package domain.location;

import java.util.Random;

import javax.microedition.location.Coordinates;

import exceptions.OutOfAreaException;


/**
 * TODO description
 *
 * @date 27.05.2008
 * @author Alfred Olschnoegger
 */

public class GameArea {
	
	private Position mPos0;
	private Position mPos1;
	
	private int xMax = 0;
	private int yMax = 0;
	
	private static final double earthRad = 6378.137; // in km
	private static final double squareLength = 10.0; // m
		
	public GameArea(double xLat,double xLong,double yLat,double yLong) {

		mPos0 = new Position(0, 0, xLat, xLong);
		mPos1 = new Position(0, 0, yLat, yLong);

		reorg();
			
		// calc dist between the 2 corners ...
		double lx = gpsLenght(xLat, xLong, yLat, xLong);
		double ly = gpsLenght(xLat, xLong, xLat, yLong);
		
		xMax = (int)(lx / squareLength);
		yMax = (int)(ly / squareLength);
		
		mPos1.setX(xMax);
		mPos1.setY(yMax);
	}
	
	public boolean contains(Position p) {
		
		if(p.getX() == 0 && p.getY() == 0){
						
			if(p.getGpsX() >= mPos0.getGpsX() && p.getGpsX() <= mPos1.getGpsX() && p.getGpsY() >= mPos0.getGpsY() && p.getGpsY() <= mPos1.getGpsY())
				return true;
		}
		
		else if((p.getX() >= mPos0.getX() && p.getX() <= mPos1.getX()) && (p.getY() >= mPos0.getY() && p.getY() <= mPos1.getY())) {
			return true;
		}
		return false;
	}
	
	
	public Position getRandPosition() {

		Random rand = new Random();				
		return new Position(rand.nextInt(xMax),rand.nextInt(yMax));
	}
	
	public Position getPosition(double gpsLatitude, double gpsLongitude) throws OutOfAreaException {
		Position p = new Position(0,0,gpsLatitude,gpsLongitude);
		if(!this.contains(p)){
			throw new OutOfAreaException();
		}
		
		double lx = gpsLenght(mPos0.getGpsX(), mPos0.getGpsY(), gpsLatitude, mPos0.getGpsY());
		double ly = gpsLenght(mPos0.getGpsX(), mPos0.getGpsY(), mPos0.getGpsX(), gpsLongitude);
		
		return new Position((int)(lx / squareLength),(int)(ly / squareLength),gpsLatitude,gpsLongitude);
	}
	
	/**
	 * sets the smaller values to X and the lager to Y
	 */
	private void  reorg() {

		if(mPos0.getGpsX() > mPos1.getGpsX()) {		
			Position tmp = mPos0.clone();
			
			mPos0.setGpsX(mPos1.getGpsX());
			mPos1.setGpsX(tmp.getGpsX());
		}
		if(mPos0.getGpsY() > mPos1.getGpsY()) {		
			Position tmp = mPos0.clone();
			
			mPos0.setGpsY(mPos1.getGpsY());
			mPos1.setGpsY(tmp.getGpsY());
		}
		
	}
	
	/*
	 * returns the distance between two points in m
	 * 
	 */
	private double gpsLenght(double lat1, double long1, double lat2, double long2){
			
		//TODO Hannse use Loc API distance ... 
		Coordinates c1 = new Coordinates(lat1, long1, 0);
		Coordinates c2 = new Coordinates(lat2, long2, 0);
		return c1.distance(c2);

	}
	
	/**
	 * moves a given position in the gameArea grid by the given values
	 * @param pos		position to modify
	 * @param byLat		movement in fields
	 * @param byLong	movement in fields
	 */
	public boolean move(Position pos, int moveX, int moveY) {
		
		if(((pos.getX() + moveX) > xMax) || ((pos.getX() + moveX) < 0))		 
			return false;
		
		if(((pos.getY() + moveY) > yMax) || ((pos.getY() + moveY) < 0))
			return false;
			
			
		pos.setX(pos.getX() + moveX);
		pos.setY(pos.getY() + moveY);
		return true;	
	}
	
	/**
	 * moves a given position in the gameArea and outside the  grid by the given values
	 * @param pos		position to modify
	 * @param byLat		movement in fields
	 * @param byLong	movement in fields
	 */
	public boolean moveUnchecked(Position pos, int moveX, int moveY) {

		boolean inside = true;
		
		if(((pos.getX() + moveX) > xMax) || ((pos.getX() + moveX) < 0))		 
			inside = false;
		
		if(((pos.getY() + moveY) > yMax) || ((pos.getY() + moveY) < 0))
			inside = false;
			
		pos.setX(pos.getX() + moveX);
		pos.setY(pos.getY() + moveY);
		return inside;	
	}
	
	public Position getX() {
		return mPos0.clone();		
	}
	
	public Position getY() {
		return mPos1.clone();
	}

}


// end of GameArea.java
